---
title: Keystatic & Astro
description: 使用 Keystatic 作为 CMS 向你的 Astro 项目添加内容
sidebar:
  label: Keystatic
type: cms
logo: keystatic
i18nReady: true
---
import { Steps } from '@astrojs/starlight/components';
import { FileTree } from '@astrojs/starlight/components';
import PackageManagerTabs from '~/components/tabs/PackageManagerTabs.astro';

[Keystatic](https://keystatic.com/) 是一个开源的无头内容管理系统，它允许你构建内容并实现与 GitHub 的同步。

:::tip
如果你要**从头开始创建一个新的 Astro + Keystatic 项目**，你可以使用 [Keystatic CLI](https://keystatic.com/docs/quick-start#keystatic-cli) 在几秒钟内生成一个新项目：

<PackageManagerTabs>
  <Fragment slot="npm">
  ```shell
  npm create @keystatic@latest
  ```
  </Fragment>
  <Fragment slot="pnpm">
  ```shell
  pnpm create @keystatic@latest
  ```
  </Fragment>
  <Fragment slot="yarn">
  ```shell
  yarn create @keystatic
  ```
  </Fragment>
</PackageManagerTabs>

选择 Astro 模板后，你就可以开始[部署你的 Keystatic + Astro 项目](#部署-keystatic--astro)了！

:::

## 前期准备

- 一个已经 [配置了适配器的](/zh-cn/guides/on-demand-rendering/) 的现有 Astro 项目。

:::note
如果你计划将 Keystatic 的数据与 GitHub 同步，确保你的 GitHub 账号拥有此项目仓库的 `write` 权限。
:::

## 安装依赖

使用你的包管理器的 `astro add` 命令，将 Markdoc（用于内容条目）和 React（用于 Keystatic 管理 UI 仪表板）的集成添加到你的 Astro 项目中。

<PackageManagerTabs>
  <Fragment slot="npm">
  ```shell
  npx astro add react markdoc
  ```
  </Fragment>
  <Fragment slot="pnpm">
  ```shell
  pnpm astro add react markdoc
  ```
  </Fragment>
  <Fragment slot="yarn">
  ```shell
  yarn astro add react markdoc
  ```
  </Fragment>
</PackageManagerTabs>

你还需要两个 Keystatic 包：

<PackageManagerTabs>
  <Fragment slot="npm">
  ```shell
  npm install @keystatic/core @keystatic/astro
  ```
  </Fragment>
  <Fragment slot="pnpm">
  ```shell
  pnpm add @keystatic/core @keystatic/astro
  ```
  </Fragment>
  <Fragment slot="yarn">
  ```shell
  yarn add @keystatic/core @keystatic/astro
  ```
  </Fragment>
</PackageManagerTabs>

## 添加 Astro 集成

在你的 Astro 配置文件中添加来自 `@keystatic/astro` 的 Astro 集成：

```js  ins={6} ins=", keystatic()"
// astro.config.mjs
import { defineConfig } from 'astro/config'

import react from '@astrojs/react'
import markdoc from '@astrojs/markdoc'
import keystatic from '@keystatic/astro'

// https://astro.build/config
export default defineConfig({
  integrations: [react(), markdoc(), keystatic()],
  output: 'static',
})
```

## 创建 Keystatic 配置文件

为了定义你的内容模式，你需要创建一个 Keystatic 配置文件。此外，如果你选择这样做，该文件还可以帮助你将项目与特定的 GitHub 仓库链接起来。

在项目的根目录下创建一个名为 `keystatic.config.ts` 的文件。在该文件中，定义你的存储类型为 `local`，并设置一个名为 `posts` 的内容集合：

```ts {8-25}
// keystatic.config.ts
import { config, fields, collection } from '@keystatic/core';

export default config({
  storage: {
    kind: 'local',
  },

  collections: {
    posts: collection({
      label: 'Posts',
      slugField: 'title',
      path: 'src/content/posts/*',
      format: { contentField: 'content' },
      schema: {
        title: fields.slug({ name: { label: 'Title' } }),
        content: fields.markdoc({
          label: 'Content',
        }),
      },
    }),
  },
});
```

:::note[已经在使用内容集合了吗？]
如果你的 Astro 项目中已经使用了 [内容集合](/zh-cn/guides/content-collections/)，请确保更新上述 schema，使其与你现有 schema 中定义的集合完全一致。
:::

现在，Keystatic 已经可以根据你的 schema 配置来管理内容了。

## 在本地运行 Keystatic

要启动 Keystatic 管理界面，你需要运行 Astro 的开发服务器：

    ```bash
    npm run dev
    ```

在浏览器中输入 `http://127.0.0.1:4321/keystatic`，即可查看正在运行的 Keystatic 管理界面。


## 创建新文章

<Steps>
1. 打开 Keystatic 管理界面，然后在仪表板中选择 “Posts” 集合。

2. 使用按钮创建一个新文章。添加标题 “我的第一篇文章” 和一些内容，然后保存文章。
 
3. 这篇文章现在应该在你的 “Posts” 集合中可见。你可以从这个管理界面查看和编辑你的文章。
 
4. 现在，返回你的 Astro 项目文件并查看 `src/content/posts` 目录，你会发现这篇新文章已经生成了一个新的 `.mdoc` 文件：
		<FileTree title="项目结构">
		- src/
		  - content/
		    - posts/
		      - **my-first-post.mdoc**
		</FileTree>

5. 打开你的代码编辑器，导航到该文件，确认你可以看到你之前输入的 Markdown 内容。例如：
		```markdown
		---
		title: 我的第一篇文章
		---
		
		这是我非常激动的第一篇文章！
		```
</Steps>

## 渲染 Keystatic 内容

你可以使用 Astro 的内容集合 API 来[查询和显示你的帖子和集合](/zh-cn/guides/content-collections/#查询集合)，就如同在其他 Astro 项目中一样。

### 显示集合列表

以下示例将展示一个帖子标题列表，每个标题都会链接到对应的帖子页面。

```tsx {4}
---
import { getCollection } from 'astro:content'

const posts = await getCollection('posts')
---
<ul>
  {posts.map(post => (
    <li>
      <a href={`/posts/${post.slug}`}>{post.data.title}</a>
    </li>
  ))}
</ul>
```

### 显示单个条目

要展示单个帖子的内容，你可以引入并使用 `<Content />` 组件，这样可以方便地[将内容渲染成 HTML](/zh-cn/guides/content-collections/#渲染正文内容)。

```tsx {4-5}
---
import { getEntry } from 'astro:content'

const post = await getEntry('posts', 'my-first-post')
const { Content } = await post.render()
---

<main>
  <h1>{post.data.title}</h1>
  <Content />
</main>

```

要了解更多关于查询、过滤、展示你的内容集合以及更多信息，请查看完整的[内容集合文档](/zh-cn/guides/content-collections/)。
## 部署 Keystatic + Astro

要部署你的网站，请参考我们的[部署指南](/zh-cn/guides/deploy/)，并按照你选择的托管服务提供商的步骤进行操作。

此外，你可能还会对[如何将 Keystatic 与 GitHub 连接](https://keystatic.com/docs/connect-to-github)感兴趣，这样可以让你在项目部署的过程中更方便地管理内容。

## 官方资源

- 查看[官方的 Keystatic 指南](https://keystatic.com/docs/installation-astro)
- [Keystatic 启动模板](https://github.com/Thinkmill/keystatic/tree/main/templates/astro)
